package com.ybt.message.manager;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;

import com.sinosoft.midplat.common.JdomUtil;
import com.ybt.configration.IYBTConfigration;
import com.ybt.configration.YBTConfigration;
import com.ybt.configration.YBTRuntimeConfiguration;
import com.ybt.message.pack.IMessagePack;
import com.ybt.message.pack.MessagePackComponent;
import com.ybt.message.unpack.IMessageUnpack;
import com.ybt.message.unpack.MessageUnpackComponent;

public class PackUnpackStrategyManager {
    private static Logger logger = Logger
            .getLogger(PackUnpackStrategyManager.class);
    private static String CONFIG_DIR = "message";
    private static String PACK_DIR =  "pack";
    private static String UNPACK_DIR = "unpack";

    private Map<String, Document> packs;
    private Map<String, Document> unpacks;
    private Map<String, IMessagePack> mpacks;
    private Map<String, IMessageUnpack> munpacks;
    private volatile static PackUnpackStrategyManager manager;

    private PackUnpackStrategyManager() {
        mpacks = new HashMap<String, IMessagePack>();
        munpacks = new HashMap<String, IMessageUnpack>();
        packs = new HashMap<String, Document>();
        unpacks = new HashMap<String, Document>();

        CONFIG_DIR = YBTConfigration.getInstance().getProperty(
                IYBTConfigration.WORKFLOW_DEPLOY_PATH)
                + File.separator + CONFIG_DIR;
        PACK_DIR = CONFIG_DIR + File.separator + PACK_DIR;
        UNPACK_DIR = CONFIG_DIR + File.separator + UNPACK_DIR;
        loadFromLocal();
    }

    public static PackUnpackStrategyManager getInstance() {
        if (manager == null) {
            synchronized (PackUnpackStrategyManager.class) {
                if (manager == null) {
                    manager = new PackUnpackStrategyManager();
                }
            }
        }
        return manager;
    }
    
    /**
     * 根据渠道名称，获取拆包实现.
     * 
     * @param channel
     *            渠道名称
     * @return 拆包实现类对象
     */
    public IMessageUnpack getMessageUnpack(String channel) {
        IMessageUnpack service = munpacks.get(channel);
        if (service == null) {
            // 打包服务没load
            IMessageUnpack decorator = new MessageUnpackComponent();
            // 打包配置文件
            Document config = unpacks.get(channel);
            if (config == null) {
                // 没有配置打包信息
                logger.debug(
                        "there isn't any unpack configration for channel [" + channel
                                + "], use the default unpack service");
            }else{
                List<Element> eProcess = config.getRootElement().getChildren("process");
                for(Element ep : eProcess){
                    String type = ep.getAttributeValue("type");
                    decorator = PackUnpackFactory.getInstance().createUnpackDecorator(type, decorator, ep);
                }
            }
            munpacks.put(channel, decorator);
            
            return decorator;
        }
        return service;

    }
    
    /**
     * 根据渠道名称，获取拆包实现.
     * 
     * @param channel
     *            渠道名称
     * @return 拆包实现类对象
     */
    public IMessagePack getMessagePack(String channel) {
        IMessagePack service = mpacks.get(channel);
        if (service == null) {
            // 打包服务没load
            IMessagePack decorator = new MessagePackComponent();
            // 打包配置文件
            Document config = packs.get(channel);
            if (config == null) {
                // 没有配置打包信息
                logger.debug(
                        "there isn't any pack configration for channel [" + channel
                                + "], use the default pack service");
            }else{
                List<Element> eProcess = config.getRootElement().getChildren("process");
                for(Element ep : eProcess){
                    String type = ep.getAttributeValue("type");
                    decorator = PackUnpackFactory.getInstance().createPackDecorator(type, decorator, ep);
                }
            }
            mpacks.put(channel, decorator);
            
            return decorator;
        }
        return service;

    }

    private void loadFromLocal() {

        try {

            // load pack配置信息
            File file = new File(PACK_DIR);
            if (file.exists()) {
                // 加载打包配置
                String[] fs = file.list();
                for (String f : fs) {
                    InputStream in = new FileInputStream(PACK_DIR
                            + File.separator + f);
                    Document doc = JdomUtil.build(in, YBTRuntimeConfiguration
                            .getInstance().getConfigFileCharset().name());
                    String channel = doc.getRootElement().getAttributeValue(
                            "channel");
                    logger.debug("load pack configration for channel ["
                            + channel + "]");
                    packs.put(channel, doc);
                }
            } else {
                // 没有打包配置目录
                logger.warn("can't find the pack configration file in "
                        + PACK_DIR);
            }

            // load unpack配置信息
            file = new File(UNPACK_DIR);
            if (file.exists()) {
                // 加载打包配置
                String[] fs = file.list();
                for (String f : fs) {
                    InputStream in = new FileInputStream(UNPACK_DIR
                            + File.separator + f);
                    Document doc = JdomUtil.build(in, YBTRuntimeConfiguration
                            .getInstance().getConfigFileCharset().name());
                    String channel = doc.getRootElement().getAttributeValue(
                            "channel");
                    logger.debug("load unpack configration for channel ["
                            + channel + "]");
                    unpacks.put(channel, doc);
                }
            } else {
                // 没有打包配置目录
                logger.warn("can't find the unpack configration file in "
                        + PACK_DIR);
            }
        } catch (Exception e) {
            throw new RuntimeException(
                    "load pack or unpack configration file error", e);
        }
    }
}
